package com.aviva.config;

import java.util.Properties;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.MethodInvokingFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.jta.JtaTransactionManager;

@Configuration
@EnableTransactionManagement
// enables @Transactional annotations. Also replacement for
// <tx:annotation-driven transaction-manager="transactionManager"/>
public class RepositoryConfig {
	// ${jdbc.driverClassName}
	@Value("${jdbc.driverClassName}")
	private String driverClassName;
	@Value("${jdbc.url}")
	private String url;
	@Value("${jdbc.username}")
	private String username;
	@Value("${jdbc.password}")
	private String password;

	@Value("${hibernate.dialect}")
	private String hibernateDialect;
	@Value("${hibernate.show_sql}")
	private String hibernateShowSql;
	@Value("${hibernate.hbm2ddl.auto}")
	private String hibernateHbm2ddlAuto;

	public RepositoryConfig() {
		System.out.println("Repository config....");
	}

	// @Bean()
	// public DataSource getDataSource()
	// {
	// DriverManagerDataSource ds = new DriverManagerDataSource();
	// ds.setDriverClassName(driverClassName);
	// ds.setUrl(url);
	// ds.setUsername(username);
	// ds.setPassword(password);
	// return ds;
	// }
	@Bean(destroyMethod = "close")
	public DataSource getDataSource() {
		org.apache.tomcat.jdbc.pool.DataSource ds = new org.apache.tomcat.jdbc.pool.DataSource();
		ds.setDriverClassName(driverClassName);
		ds.setUrl(url);
		ds.setUsername(username);
		ds.setPassword(password);
		ds.setInitialSize(10);
		ds.setMaxActive(10);
		ds.setMaxIdle(10);
		ds.setMinIdle(1);

		return ds;
	}

	// @Bean
	// @Autowired
	// public HibernateTransactionManager transactionManager(SessionFactory
	// sessionFactory)
	// {
	// HibernateTransactionManager htm = new HibernateTransactionManager();
	// htm.setSessionFactory(sessionFactory);
	// return htm;
	// }

	// @Bean
	// @Autowired
	// public HibernateTemplate getHibernateTemplate(SessionFactory
	// sessionFactory)
	// {
	// HibernateTemplate hibernateTemplate = new
	// HibernateTemplate(sessionFactory);
	// return hibernateTemplate;
	// }

	@Bean
	public LocalSessionFactoryBean getSessionFactory() {
		LocalSessionFactoryBean asfb = new LocalSessionFactoryBean();
		asfb.setDataSource(getDataSource());
		asfb.setHibernateProperties(getHibernateProperties());
		asfb.setPackagesToScan(new String[] { "com.aviva" });
		asfb.setJtaTransactionManager(getTransactionManager());
		return asfb;
	}

	@Bean
	public Properties getHibernateProperties() {
		Properties properties = new Properties();
		properties.put("hibernate.dialect", hibernateDialect);
		properties.put("hibernate.show_sql", hibernateShowSql);
		properties.put("hibernate.hbm2ddl.auto", hibernateHbm2ddlAuto);
		properties.put("hibernate.cache.use_second_level_cache", "true");
		properties.put("hibernate.cache.use_query_cache", "true");
//		properties.put("hibernate.cache.infinispan.cachemanager", "cacheManager");
		properties.put("hibernate.generate_statistics", "true");
		properties.put("hibernate.cache.region.factory_class", "org.hibernate.cache.infinispan.InfinispanRegionFactory");
		properties.put("hibernate.cache.infinispan.cfg", "infinispan.xml");
		properties.put("hibernate.current_session_context_class", "com.aviva.config.TransactionAwareSessionContext");// Hibernate
																														// cannot
																														// get
																														// current
																														// session
																														// if
																														// this
																														// property
																														// not
																														// set
																														// or
																														// there
																														// is
																														// no
																														// @Transactional
																														// at
																														// repository
																														// code(Spring3
																														// and
																														// Hibernate4
																														// compatibility
																														// problem)
		// properties.put("hibernate.session_factory_name",
		// "jndi/composite/name);// The org.hibernate.SessionFactory will be
		// automatically bound to this name in JNDI after it has been created.

		return properties;
	}

	// @Bean(name="arjunaTransactionManager")
	// public com.arjuna.ats.jta.TransactionManager
	// getArjunaTransactionManager(){
	// return new com.arjuna.ats.jta.TransactionManager();
	// }
	// @Bean(name="arjunaUserTransaction")
	// public com.arjuna.ats.jta.UserTransaction getArjunaUserTransaction(){
	// return new com.arjuna.ats.jta.UserTransaction();
	// }

	// @DependsOn({"arjunaUserTransaction","arjunaTransactionManager"})
	@Bean(name = "transactionManager")
	public org.springframework.transaction.jta.JtaTransactionManager getTransactionManager() {
		org.springframework.transaction.jta.JtaTransactionManager transactionManager = new JtaTransactionManager(com.arjuna.ats.jta.UserTransaction.userTransaction(), com.arjuna.ats.jta.TransactionManager.transactionManager());
		return transactionManager;
	}

	@Bean(name = "systemPrereqs")
	public org.springframework.beans.factory.config.MethodInvokingFactoryBean getMethodInvokingFactoryBean() {
		org.springframework.beans.factory.config.MethodInvokingFactoryBean bean = new MethodInvokingFactoryBean();
		bean.setTargetObject(System.getProperties());
		bean.setTargetMethod("putAll");
		Properties arguments = new Properties();
		arguments.setProperty("com.arjuna.ats.arjuna.coordinator.defaultTimeout", "60");
		arguments.setProperty("com.arjuna.ats.arjuna.objectstore.objectStoreDir", "/tmp/jbosstm/tx/a");
		arguments.setProperty("ObjectStoreEnvironmentBean.objectStoreDir", "/tmp/jbosstm/tx/a");
		bean.setArguments(new Object[] { arguments });
		return bean;
	}
}
